Skip to content

Feature/try webtools inscentives#382

Open
MSACC wants to merge 17 commits intomasterfrom
feature/try-webtools-inscentives
Open

Feature/try webtools inscentives#382
MSACC wants to merge 17 commits intomasterfrom
feature/try-webtools-inscentives

Conversation

@MSACC
Copy link
Collaborator

@MSACC MSACC commented Mar 1, 2026

What does it do?

Adds an incentive/trial system for pro addons in the Webtools admin UI:

  • Locked addon items appear in the sidebar navigation with a lock icon when a pro addon is not installed
  • Clicking a locked addon opens a TrialModal showcasing the addon's features and value proposition
  • The Overview page shows both installed addons and locked pro addons (Redirects, Links, Breadcrumbs)
  • Addon detection is based on plugin package name (not UI label) to support translations
  • New components: LockedAddonMenuItem, TrialCallToAction, TrialModal, ProAddonCard

Why is it needed?

To make users aware of available pro addons and provide a clear upgrade path when they encounter features that require a paid plan.

How to test it?

  1. yarn develop + yarn playground:develop
  2. Open Webtools in the admin → http://localhost:1337/admin
  3. Sidebar shows locked addon items (Redirects, Links, Breadcrumbs) with a lock icon
  4. Click a locked addon → TrialModal opens with features and CTA
  5. "Start free trial" button links to the polar.sh checkout page

Related issue(s)/PR(s)

N/A

MSACC added 2 commits March 1, 2026 15:04
Introduce a LinksOverview admin screen and register it in the playground admin app. Update addon detection logic in App and Overview to use addon labels/names (case-insensitive) to determine installed vs locked Pro addons, add lockedProAddons and hasProLicense helpers, and only show the "Try Premium" CTA when no Pro addon is installed. Add playground changes for local testing: include webtools addon deps and activation metadata in package.json, add a WEBTOOLS license entry to .env, add a scoped .yarnrc.yml for the pluginpal registry, and update generated types to include breadcrumbs and redirects content types. (yarn.lock updated to reflect dependency additions.)
@changeset-bot
Copy link

changeset-bot bot commented Mar 1, 2026

🦋 Changeset detected

Latest commit: 692f41e

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
strapi-plugin-webtools Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@MSACC MSACC requested a review from boazpoolman March 1, 2026 14:35
MSACC added 4 commits March 1, 2026 15:39
Add generated TypeScript build info file (dist/tsconfig.tsbuildinfo) produced by the TypeScript build. Also apply updates to packages/core/admin/components/TrialModal/index.tsx — minor changes to the TrialModal component were made alongside the build output.
@codecov
Copy link

codecov bot commented Mar 1, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 35.96%. Comparing base (af063d7) to head (692f41e).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #382   +/-   ##
=======================================
  Coverage   35.96%   35.96%           
=======================================
  Files           2        2           
  Lines         723      723           
  Branches      172      172           
=======================================
  Hits          260      260           
  Misses        368      368           
  Partials       95       95           
Flag Coverage Δ
unit 35.96% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.


// Get list of installed addon labels (e.g., "Redirects", "Links", "Breadcrumbs")
const installedAddonLabels = routerComponents
.map((route) => route.label?.toLowerCase())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better not to map this to the route label. That would cause this to break when those labels are translated. You could use this query to find all the enabled addons:

const addons = useQuery('addons', async () => get<WebtoolsAddonInfo[]>('/webtools/info/addons'));

Then we should match on the package name rather than the label.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5d7ff4b — now using useQuery('addons', ...) and matching on plugin package name instead of route label.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rather have this file be in the links addon itself. Then when we want to actually implement that links overview page, we don't need to remove this page in the core plugin.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5d7ff4b — file removed from core. Will live in the links addon once that's implemented.

const installedAddons = Object.values(addons.data.data || {});

// Get list of installed addon names (e.g., "Redirects", "Links", "Breadcrumbs")
const installedAddonNames = installedAddons.map((addon) => addon.info.addonName.toLowerCase());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, don't map to the addonName, but to the package name to allow translatability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5d7ff4b — now matching on info.name (plugin package name) instead of addonName.

export default {
register(app: any) {
// Register Links addon overview screen
const webtoolsPlugin = app.getPlugin('webtools');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be removed if we inject the route from the links plugin.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 5d7ff4b — LinksOverview registration removed.

playground/.env Outdated
ADMIN_JWT_SECRET=tobemodified
JWT_SECRET=tobemodified

WEBTOOLS_LICENSE_KEY=WEBTOOLS-4F4D6E86-270C-461A-B1FB-F58B5A707793
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

M8 ..

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in b980e9f + fa72039.env removed from git. .yarnrc.yml also contained the key and has been removed as well. Key has been rotated.

"sitemap": "strapi-sitemap"
},
"dependencies": {
"@pluginpal/webtools-addon-breadcrumbs": "^1.0.3",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These should be removed from the core playground.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 94a0a8d — addon dependencies removed from core playground.

MSACC and others added 7 commits March 2, 2026 14:58
Removed unused plugin dependencies from package.json
Replace label-based addon detection with package-name-based detection
using the addons API (/webtools/info/addons). This prevents breakage
when addon labels are translated.

- App/index.tsx: query addons API, match on info.name vs packageName
- Overview/index.tsx: use info.name (plugin name) vs proAddon.packageName
- Remove LinksOverview screen from core (belongs in the links addon)
- Clean up playground/app.tsx (remove LinksOverview injection)
- Add WEBTOOLS_LICENSE_KEY placeholder to playground/.env.example

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The .yarnrc.yml contained a hardcoded npmAuthToken (license key).
Since all @pluginpal/* packages have been removed from the playground
dependencies, the private registry config is no longer needed.

Regenerated yarn.lock after dependency cleanup in previous commit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove no-confusing-arrow violation in getPluginName (use block body)
- Fix max-len violations by shortening inline comments
- Remove no-unnecessary-type-assertion in App/index.tsx

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The .env was accidentally deleted from git tracking in b980e9f.
Tests require it to boot the Strapi instance (ADMIN_JWT_SECRET etc.).
Restored with placeholder values only — no real secrets.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@MSACC MSACC requested a review from boazpoolman March 14, 2026 12:08
MSACC added 3 commits March 14, 2026 13:16
Introduce CLAUDE.md to guide Claude Code agents working with this repository. The file documents project structure (packages, playground), development setup and workflows (yarn, playground, watch builds), testing (unit/integration/e2e), linting and TypeScript checks, plugin architecture (server/admin entry points, URL patterns/aliases, middlewares, services), addon system and admin UI integration, configuration examples, common development patterns, release process, and troubleshooting tips.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants